class CodeFile < ActiveRecord::Base
  belongs_to :widget
  
  validates_presence_of :name
  validates_presence_of :widget_id
  
  validates_uniqueness_of :name, :scope => :widget_id
  
  acts_as_runnable_code :classes => ["DataSystem"]
  
  
  def render_view(hub_widget, options = {:timeout => 1.0})
    html = run_view(hub_widget.root_object, options)
  end
    
  def run(toplevel_object = nil, options = {})
    options[:timeout] ||= self.class.runnable_code_options[:timeout] 
    s = sandbox_plus_more
    s.set(:toplevel, ActsAsWrappedClass::WrapperFinder.find_wrapper_for(toplevel_object))
    s.set(:code, self.code)    
    s.eval("eval(code, toplevel.send(:binding))", options)
  end
  
  protected
  
  def sandbox_plus_more
    s = sandbox
    classes = [ERB, ERB::Util, CGI, ActionView::Helpers::TagHelper]#, HTML::Document, ActionView::Helpers::TextHelper]
    classes.each do |klass|
      s.import klass
    end    
    
    ref_classes = [Hpricot::Text, Hpricot, Net::HTTP, URI]
    ref_classes.each do |klass|
      klass.constants.each do |cname|
              con = klass.const_get(cname)
              s.ref con if con.is_a?(Class)            
            end      
      s.ref klass
    end
    s    
  end
  
  def expand_class(klass)
    klasses = Array(klass)
    results = klasses.dup
    while !klasses.empty?
      klass.constants.each do |cname|
        con = klass.const_get(cname)
        klasses << con if con.is_a?(Class)            
      end            
    end
    results
  end
  
  def run_view(toplevel_object = nil, options = {})
    options[:timeout] ||= self.class.runnable_code_options[:timeout] 
    s = sandbox_plus_more     
    s.set(:toplevel, ActsAsWrappedClass::WrapperFinder.find_wrapper_for(toplevel_object))        
    s.set(:code, self.code)
    result = s.eval("ERB.new(code).result(toplevel.send(:binding))", options)    
  end    
end